#include <bits/stdc++.h>
using namespace std;

#define ONLINE_JUDGE

#ifndef ONLINE_JUDGE
#define dbg(x...) { cerr << "\033[32;1m" << #x << " -> "; err(x); }
void err() { cerr << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cerr << a << ' '; err(x...); }
#else
#define dbg(...)
#endif

typedef long long LL;

const int N = 1e3 + 5, M = 1e6 + 5;

namespace dinic
{
struct E
{
    int to;
    LL cp;
    E(int to = 0, LL cp = 0) : to(to), cp(cp) {}
};
struct Dinic
{
    static const int INF = 0x7fffffff;
    int m, s, t, n;

    E edges[M];
    int ecnt;
    vector<int> G[N];

    int d[N], cur[N];


    void init(int n, int m, int s, int t, int u[], int v[], int w[])
    {
        this->s = s;
        this->t = t;
        this->n = n;
        this->m = m;
        ecnt = 0;
        for (int i = 0; i <= n; ++i)
            G[i].clear();

        for (int i = 0; i < m; ++i)
        {
            // printf("add: %d %d %d\n", u[i], v[i], w[i]);
            addedge(u[i], v[i], w[i]);
            addedge(v[i], u[i], w[i]);
        }
    }

    void addedge(int u, int v, LL cap)
    {
        edges[ecnt++] = E(v, cap);
        edges[ecnt++] = E(u, 0);
        G[u].push_back(ecnt-2);
        G[v].push_back(ecnt-1);
    }

    bool bfs()
    {
        memset(d, 0, sizeof(int) * (n + 2));
        queue<int> Q;
        Q.push(s);
        d[s] = 1;
        while (!Q.empty())
        {
            int x = Q.front();
            Q.pop();
            for (int &i : G[x])
            {
                E &e = edges[i];
                if (!d[e.to] && e.cp > 0)
                {
                    d[e.to] = d[x] + 1;
                    Q.push(e.to);
                }
            }
        }
        return d[t];
    }

    LL DFS(int u, LL cp)
    {
        if (u == t || !cp)
            return cp;
        LL tmp = cp;
        LL f;
        for (int &i = cur[u]; i < (int)G[u].size(); ++i)
        {
            E &e = edges[G[u][i]];
            if (d[u] + 1 == d[e.to])
            {
                f = DFS(e.to, min(cp, e.cp));
                e.cp -= f;
                edges[G[u][i] ^ 1].cp += f;
                cp -= f;
                if (!cp)
                    break;
            }
        }
        return tmp - cp;
    }

    LL go(int S = -1, int T = -1)
    {
        if ((~S) && (~T))
        {
            s = S;
            t = T;
        }
        LL flow = 0;
        while (bfs())
        {
            memset(cur, 0, sizeof(int) * (n + 1));
            flow += DFS(s, INF);
        }
        return flow;
    }

    // bool deep[N];

    void cut(bool deep[], int cl = 1, int cr = N - 1)
    {
        memset(deep + cl, 0, sizeof(bool) * (cr - cl + 1));
        queue<int> q;
        q.push(s);
        while (!q.empty())
        {
            int now = q.front();
            q.pop();
            deep[now] = true;
            for (int eid : G[now])
            {
                E &e = edges[eid];
                if (e.cp && !deep[e.to])
                {
                    q.push(e.to);
                }
            }
        }
    }
};
} // namespace dinic

struct MinCutTree
{
    dinic::Dinic dc;

    bool deep[N];
    int *u, *v, *w, n, m;
    int node[N], tmp1[N], tmp2[N];

    vector<pair<int, int>> *G;

    void add(int u, int v, int w)
    {
        G[u].emplace_back(v, w);
        G[v].emplace_back(u, w);
    }

    void init(int n, int m, int u[], int v[], int w[], vector<pair<int, int>> G[])
    {
        this->n = n;
        this->m = m;
        this->u = u;
        this->v = v;
        this->w = w;
        this->G = G;
        dbg("mct.init", n, m);
        for (int i=0; i<m; ++i)
            dbg(i, u[i], v[i], w[i]);
    }

    void build(int l, int r)
    {
        if (l == r)
            return;
        int s = node[l], t = node[l + 1];
        dc.init(n, m, s, t, u, v, w);
        int res = dc.go();
        dc.cut(deep, 1, n);
        dbg(s, t, res);
        add(s, t, res);
        int tcnt1 = 0, tcnt2 = 0;
        for (int i = l; i <= r; ++i)
        {
            if (deep[node[i]])
                tmp1[tcnt1++] = node[i];
            else
                tmp2[tcnt2++] = node[i];
        }
        // int ncnt = 0;
        for (int i = 0; i < tcnt1; ++i)
            node[l + i] = tmp1[i];
        for (int i = 0; i < tcnt2; ++i)
            node[l + tcnt1 + i] = tmp2[i];
        build(l, l + tcnt1 - 1);
        build(l + tcnt1, r);
    }

    void go()
    {
        for (int i = 1; i <= n; ++i)
            node[i] = i;
        build(1, n);
    }
} mct;
struct ST
{
    static const int SP = 20; 
    int dat[SP][N];
    static int Log[N], p2[SP];
    static void init()
    {
        Log[1] = 0;
        for (int i=2; i<N; ++i)
            Log[i] = Log[i >> 1] + 1;
        p2[0] = 1;
        for (int i=1; i<SP; ++i)
            p2[i] = p2[i-1] << 1;
    }

    void init(int a[], int n)
    {
        for (int i=1; i<=n; ++i)
        {
            dat[0][i] = a[i];
        }
        for (int i=1; i<SP; ++i)
        for (int j=1; j<=n; ++j)
            dat[i][j] = min(dat[i-1][j], dat[i-1][j+p2[i-1]]);
    }

    int q(int l, int r)
    {
        int Lg = Log[r-l+1];
        dbg(Lg, l, r);
        return min(dat[Lg][l], dat[Lg][r-p2[Lg]+1]);
    }
};

int ST::Log[N], ST::p2[SP];

int dep[N], id[N], fa[N];
vector<pair<int, int>> G[N];
struct HLD
{
    int top[N], d[N], f[N], son[N], rid[N];
    int dfn;

    int siz[N];
    ST st;

    void dfs1(int u, int la, int depth)
    {
        dep[u] = depth;
        fa[u] = la;
        son[u] = -1;
        siz[u] = 1;
        for (const auto &p : G[u])
        {
            int v = p.first;
            if (v == la)
                continue;
            dfs1(v, u, depth + 1);
            siz[u] += siz[v];
            if (!~son[u] || siz[v] > siz[son[u]])
                son[u] = v;
        }
    }

    void dfs2(int u, int la, int t)
    {
        id[u] = ++dfn;
        rid[id[u]] = u;
        top[id[u]] = id[t];
        d[id[u]] = dep[u];
        f[id[u]] = id[la];
        if (~son[u]) dfs2(son[u], u, t);
        for (const auto &p : G[u])
        {
            int v = p.first;
            if (v == la)
                continue;
            if (v != son[u])
                dfs2(v, u, v);
        }
    }
    int lca(int u, int v)
    {
        for (u = id[u], v = id[v]; top[u] != top[v]; u = f[top[u]])
        {
            if (d[top[u]] < d[top[v]])
                swap(u, v);
        }

        if (d[u] < d[v])
            swap(u, v);
        return rid[v];
    }

    LL go(int u, int v)
    {
        dbg("go", u, v);
        LL ans = 1e18;
        for (u = id[u], v = id[v]; top[u] != top[v]; u = f[top[u]])
        {
            if (d[top[u]] < d[top[v]])
                swap(u, v);
            // ans += bit.sum(v, u);
            dbg(top[u], u);
            ans = min(ans, st.q(top[u], u) * 1LL);
        }
        
        if (d[u] < d[v])
        {
            swap(u, v);
            // ans += st.q(v+1, u);
        }
        
        dbg(u, v, d[u], d[v]);
        if (u != v) 
            ans = min(ans, (LL)st.q(v+1, u));
        return ans;
    }

    void init(int n)
    {
        dfs1(1, 1, 1);
        dfs2(1, 1, 1);
        static int a[N];
        a[1] = 0;
        for (int i=1; i<=n; ++i)
        {
            for (const auto &p : G[i])
            {
                if (fa[i] == p.first)
                {
                    a[id[i]] = p.second;
                }
            }
        }

        for (int i=1; i<=n; ++i) dbg(i, a[i], id[i], top[i]);
        st.init(a, n);
    }
} hld;

int n, m;

int u[M], v[M], w[M];
unordered_map<int, int> mp;
inline int checkin(int x)
{
    static int cnt = 0;
    if (mp.count(x)) return mp[x];
    else {
        ++cnt;
        mp[x] = cnt;
        dbg(x);
        return cnt;
    }
}

int main(int argc, char const *argv[])
{
    ST::init();
    scanf("%d%d", &n, &m);
    // ++n;
    for (int i = 0; i < m; ++i)
    {
        scanf("%d%d%d", &u[i], &v[i], &w[i]);
        // ++u[i]; ++v[i];
        u[i] = checkin(u[i]); v[i] = checkin(v[i]);
    }
    n = mp.size();
    dbg(n);
    mct.init(n, m, u, v, w, G);
    mct.go();

    #ifndef ONLINE_JUDGE
    for (int i=1; i<=n; ++i)
    {
        printf("%d: ", i);
        for (const auto &p : G[i])
            printf(" {%d %d}", p.first, p.second);
        puts("");
    }
    #endif

    hld.init(n);
    int q;
    scanf("%d", &q);
    for (int i = 0; i < q; ++i)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        u = checkin(u); v = checkin(v);
        printf("%lld\n", hld.go(u, v));
    }

    return 0;
}
